﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Threading;
using System.Diagnostics;

namespace RitS.Physics
{
    public static class GravityPhysicsTools
    {
        private static double GravitationalConstant = 6.673 * Math.Pow(10, -13);
        private static long SecondsPerMs = 100;

        public static void ApplyGravityTick(ref List<IPhysicsBody> GravityBodies, ref List<IPhysicsBody> NonGravityBodies, int ticks)
        {
            for (int i = 0; i < GravityBodies.Count; i++)
            {
                Vector force = new Vector(0, 0);
                for (int j = i+1; j < GravityBodies.Count; j++)
                {
                    Vector newForce = GetForce(GravityBodies[i], GravityBodies[j]);
                    GravityBodies[i].ApplyForceTick(newForce * -1, ticks);
                    GravityBodies[j].ApplyForceTick(newForce, ticks );
                }
                GravityBodies[i].ApplyVelocityTick(ticks);                    
            }
        }

        public static Vector GetForce(IPhysicsBody body1, IPhysicsBody body2)
        {
            Vector forceVector = new Vector();
            Vector distance = body1.Position - body2.Position;

            double force = (GravitationalConstant * body1.Mass * body2.Mass) / distance.LengthSquared;

            distance.Normalize();

            forceVector.X = distance.X * force;
            forceVector.Y = distance.Y * force;

            return forceVector;
        }

        public static void ExecutePhysicsLoop()
        {
            Action newAction = (Action)(delegate
            {
                long lastTick;
                Stopwatch watch = Stopwatch.StartNew();
                while (true)
                {
                    lastTick = watch.ElapsedMilliseconds;
                    watch.Restart();

                    Thread.Sleep(1);
                    ApplyGravityTick(ref MainWindow.gravityBodies, ref MainWindow.gravityBodies, (int)lastTick);
                }
            });
            newAction.BeginInvoke(null, null);
        }
    }
}
